
#include<stdio.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<fcntl.h>
#include<sys/select.h>
#include<unistd.h>
#include<json/json.h>
#include<string>
#include<iostream>

#define MAXLINE 1024

using namespace std;

int main(int argc, char **argv) {
    int sockfd, n;
    int stdinfd = 0;
    char recvline[MAXLINE];
    struct sockaddr_in servaddr;
    if (argc != 2) {
        printf("arguments number must be two\n");
        return -1;
    }
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("socket error\n");
        return -1;
    }
    
    int option = fcntl(sockfd, F_GETFL);
    bzero(&servaddr, sizeof(servaddr));
    fd_set rset;
    FD_ZERO(&rset);
    FD_SET(sockfd, &rset);
    FD_SET(stdinfd, &rset);

    int maxfd = sockfd + 1;

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(9000);
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
        printf("inet_pton error\n");
        return -1;
    }
    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        printf("connect error\n");
        return -1;
    }
    int ret = fcntl(sockfd, F_SETFL, option | O_NONBLOCK);
    Json::Value req_msg_json;
    Json::FastWriter wr;
    Json::Reader reader;
    req_msg_json["type"] = "m01";
    string req_msg;
    req_msg = wr.write(req_msg_json);
    sprintf(recvline, "synchronization");
    cout << "req_msg " << req_msg << endl;
    int write_bytes = write(sockfd, req_msg.c_str(), strlen(req_msg.c_str()) + 1);
    cout << "write_bytes:" << write_bytes << endl;
    char ip[16];
    while(1) {
        FD_SET(sockfd, &rset);
        FD_SET(stdinfd, &rset);
        maxfd = sockfd + 1;
        //printf("input the message:");
        select(maxfd, &rset, NULL, NULL, NULL);
        if (FD_ISSET(stdinfd, &rset)) {
            scanf("%s", ip);
            scanf("%s", recvline);
            req_msg_json["type"] = "m00";
            req_msg_json["ip"] = string(ip);
            req_msg_json["msg"] = string(recvline);
            req_msg = wr.write(req_msg_json);
            write(sockfd, req_msg.c_str(), strlen(req_msg.c_str()) + 1);
        }
        if (FD_ISSET(sockfd, &rset)) {
            printf("readable......\n");
            while ((n = read(sockfd, recvline, MAXLINE))  != -1 && n != 0) {
                printf("server: %d %s\n", n, recvline);
            }
            if (n == 0) {
                break;
            } 
        }
        //printf("write:%d\n",strlen(recvline) + 1);
    }
    return 0;
}
